Modified patch from muppet <scott@asofyet.org> to keep child directories
authorJonathan Blandford <jrb@gnome.org>
Thu, 4 Mar 2004 06:47:54 +0000 (06:47 +0000)
committerJonathan Blandford <jrb@src.gnome.org>
Thu, 4 Mar 2004 06:47:54 +0000 (06:47 +0000)
Thu Mar  4 01:32:19 2004  Jonathan Blandford  <jrb@gnome.org>

        * gtk/gtkpathbar.c (gtk_path_bar_set_path): Modified patch from
        muppet <scott@asofyet.org> to keep child directories around if we
        change to a child.

        * gtk/gtkpathbar.c (_gtk_path_bar_set_home_icon): Start of
        icon-setting functions.  Not used yet.
        (_gtk_path_bar_set_root_icon): Ditto.

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkfilechooserdefault.c
gtk/gtkpathbar.c
gtk/gtkpathbar.h

index 96f8e491e9f7c8642375f756ce8e60c8890d21a7..a3b6b982f2b92408a11c0943940d10f6dffa9cb7 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+Thu Mar  4 01:32:19 2004  Jonathan Blandford  <jrb@gnome.org>
+
+       * gtk/gtkpathbar.c (gtk_path_bar_set_path): Modified patch from
+       muppet <scott@asofyet.org> to keep child directories around if we
+       change to a child.
+
+       * gtk/gtkpathbar.c (_gtk_path_bar_set_home_icon): Start of
+       icon-setting functions.  Not used yet.
+       (_gtk_path_bar_set_root_icon): Ditto.
+       
 Thu Mar  4 00:31:54 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtktextview.c (extend_selection): 
index 96f8e491e9f7c8642375f756ce8e60c8890d21a7..a3b6b982f2b92408a11c0943940d10f6dffa9cb7 100644 (file)
@@ -1,3 +1,13 @@
+Thu Mar  4 01:32:19 2004  Jonathan Blandford  <jrb@gnome.org>
+
+       * gtk/gtkpathbar.c (gtk_path_bar_set_path): Modified patch from
+       muppet <scott@asofyet.org> to keep child directories around if we
+       change to a child.
+
+       * gtk/gtkpathbar.c (_gtk_path_bar_set_home_icon): Start of
+       icon-setting functions.  Not used yet.
+       (_gtk_path_bar_set_root_icon): Ditto.
+       
 Thu Mar  4 00:31:54 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtktextview.c (extend_selection): 
index 96f8e491e9f7c8642375f756ce8e60c8890d21a7..a3b6b982f2b92408a11c0943940d10f6dffa9cb7 100644 (file)
@@ -1,3 +1,13 @@
+Thu Mar  4 01:32:19 2004  Jonathan Blandford  <jrb@gnome.org>
+
+       * gtk/gtkpathbar.c (gtk_path_bar_set_path): Modified patch from
+       muppet <scott@asofyet.org> to keep child directories around if we
+       change to a child.
+
+       * gtk/gtkpathbar.c (_gtk_path_bar_set_home_icon): Start of
+       icon-setting functions.  Not used yet.
+       (_gtk_path_bar_set_root_icon): Ditto.
+       
 Thu Mar  4 00:31:54 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtktextview.c (extend_selection): 
index 96f8e491e9f7c8642375f756ce8e60c8890d21a7..a3b6b982f2b92408a11c0943940d10f6dffa9cb7 100644 (file)
@@ -1,3 +1,13 @@
+Thu Mar  4 01:32:19 2004  Jonathan Blandford  <jrb@gnome.org>
+
+       * gtk/gtkpathbar.c (gtk_path_bar_set_path): Modified patch from
+       muppet <scott@asofyet.org> to keep child directories around if we
+       change to a child.
+
+       * gtk/gtkpathbar.c (_gtk_path_bar_set_home_icon): Start of
+       icon-setting functions.  Not used yet.
+       (_gtk_path_bar_set_root_icon): Ditto.
+       
 Thu Mar  4 00:31:54 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtktextview.c (extend_selection): 
index 96f8e491e9f7c8642375f756ce8e60c8890d21a7..a3b6b982f2b92408a11c0943940d10f6dffa9cb7 100644 (file)
@@ -1,3 +1,13 @@
+Thu Mar  4 01:32:19 2004  Jonathan Blandford  <jrb@gnome.org>
+
+       * gtk/gtkpathbar.c (gtk_path_bar_set_path): Modified patch from
+       muppet <scott@asofyet.org> to keep child directories around if we
+       change to a child.
+
+       * gtk/gtkpathbar.c (_gtk_path_bar_set_home_icon): Start of
+       icon-setting functions.  Not used yet.
+       (_gtk_path_bar_set_root_icon): Ditto.
+       
 Thu Mar  4 00:31:54 2004  Matthias Clasen  <maclas@gmx.de>
 
        * gtk/gtktextview.c (extend_selection): 
index eaecbc962e23f1afd26c4e712346aefa21dfeb01..9619ce07b5b6dfa4ebcb408ddb518ee1e2411f22 100644 (file)
@@ -1930,7 +1930,7 @@ file_pane_create (GtkFileChooserDefault *impl,
   hbox = gtk_hbox_new (FALSE, 12);
   gtk_widget_show (hbox);
   impl->browse_path_bar = g_object_new (GTK_TYPE_PATH_BAR, NULL);
-  g_signal_connect (impl->browse_path_bar, "path_clicked", G_CALLBACK (path_bar_clicked), impl);
+  g_signal_connect (impl->browse_path_bar, "path-clicked", G_CALLBACK (path_bar_clicked), impl);
   gtk_widget_show_all (impl->browse_path_bar);
   gtk_box_pack_start (GTK_BOX (hbox), impl->browse_path_bar, TRUE, TRUE, 0);
 
@@ -2842,7 +2842,7 @@ gtk_file_chooser_default_set_current_folder (GtkFileChooser    *chooser,
   GError *error;
 
   error = NULL;
-  if (!gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), path, impl->file_system, &error))
+  if (!_gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), path, impl->file_system, &error))
     {
       error_dialog (impl,
                    _("Could not set current folder: %s"),
index 66893493ae18846d365efb4ab4bd1dc007493d56..7aa9faf22fce304358aefbd9485620554bc591ff 100644 (file)
@@ -131,6 +131,12 @@ gtk_path_bar_finalize (GObject *object)
 
   path_bar = GTK_PATH_BAR (object);
   g_list_free (path_bar->button_list);
+  if (path_bar->home_directory)
+    gtk_file_path_free (path_bar->home_directory);
+  if (path_bar->home_icon)
+    g_object_unref (path_bar->home_icon);
+  if (path_bar->root_icon)
+    g_object_unref (path_bar->home_icon);
 
   G_OBJECT_CLASS (gtk_path_bar_parent_class)->finalize (object);
 }
@@ -570,70 +576,123 @@ button_clicked_cb (GtkWidget *button,
   GtkFilePath *file_path;
 
   path_bar = button->parent;
-  g_assert (path_bar);
+  g_assert (GTK_IS_PATH_BAR (path_bar));
 
-  file_path = gtk_file_path_new_dup ((char *)data);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+
+  file_path = g_object_get_data (G_OBJECT (button), "gtk-path-bar-button-path");
   g_signal_emit (path_bar, path_bar_signals [PATH_CLICKED], 0, file_path);
-  gtk_file_path_free (file_path);
 }
 
-static GtkWidget *
-make_directory_button (const char  *dir_name,
-                      GtkFilePath *path,
-                      gboolean     current_dir)
+static void
+update_button_appearance (GtkWidget *button,
+                         gboolean   current_dir)
 {
-  GtkWidget *button, *label;
-      
-  button = gtk_toggle_button_new ();
-  if (current_dir)
-    {
-      /* Yay gsignal! */
-      g_signal_connect (G_OBJECT (button), "toggled",
-                       G_CALLBACK (gtk_toggle_button_set_active),
-                       GINT_TO_POINTER (TRUE));
-    }
-  else
-    {
-      gchar *str;
-
-      /* FIXME: gtk_file_path_free is not be a function!! I have to
-       * copy it to a string in order to manage this correctly */
-      str = g_strdup (gtk_file_path_get_string (path));
-      g_signal_connect (button, "clicked",
-                       G_CALLBACK (button_clicked_cb),
-                       str);
-      g_object_weak_ref (G_OBJECT (button), (GWeakNotify) g_free, str);
-    }
+  GtkWidget *label;
+  const gchar *dir_name;
 
-  label = gtk_label_new (NULL);
+  dir_name = (const gchar *) g_object_get_data (G_OBJECT (button),
+                                               "gtk-path-bar-button-dir-name");
+  label = gtk_bin_get_child (GTK_BIN (button));
 
   if (current_dir)
     {
-      gchar *label_str;
-      
-      label_str = g_markup_printf_escaped ("<b>%s</b>", dir_name);
-      gtk_label_set_markup (GTK_LABEL (label), label_str);
-      g_free (label_str);
+      char *markup;
 
-      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
+      markup = g_markup_printf_escaped ("<b>%s</b>", dir_name);
+      gtk_label_set_markup (GTK_LABEL (label), markup);
+      g_free (markup);
     }
   else
     {
       gtk_label_set_text (GTK_LABEL (label), dir_name);
     }
 
+  if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)) != current_dir)
+    {
+      g_signal_handlers_block_by_func (G_OBJECT (button), button_clicked_cb, NULL);
+      gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), current_dir);
+      g_signal_handlers_unblock_by_func (G_OBJECT (button), button_clicked_cb, NULL);
+    }
+}
+
+/* Since gtk_file_path_free() can be a macro, we provide a real function that
+ * can be used as a callback.
+ */
+static void
+file_path_destroy (GtkFilePath *path)
+{
+  gtk_file_path_free (path);
+}
+
+static GtkWidget *
+make_directory_button (const char  *dir_name,
+                      GtkFilePath *path,
+                      gboolean     current_dir)
+{
+  GtkWidget *button, *label;
+      
+  button = gtk_toggle_button_new ();
+  label = gtk_label_new (NULL);
+
+  g_signal_connect (button, "clicked",
+                   G_CALLBACK (button_clicked_cb),
+                   NULL);
+
+  g_object_set_data_full (G_OBJECT (button), "gtk-path-bar-button-dir-name",
+                         g_strdup (dir_name),
+                         (GDestroyNotify) g_free);
+  g_object_set_data_full (G_OBJECT (button), "gtk-path-bar-button-path",
+                         gtk_file_path_new_dup (gtk_file_path_get_string (path)),
+                         (GDestroyNotify) file_path_destroy);
+
   gtk_container_add (GTK_CONTAINER (button), label);
   gtk_widget_show_all (button);
 
+  update_button_appearance (button, current_dir);
+
   return button;
 }
 
+static gboolean
+gtk_path_bar_check_parent_path (GtkPathBar         *path_bar,
+                               const GtkFilePath  *file_path,
+                               GtkFileSystem      *file_system)
+{
+  GList *list;
+  GList *current_path = NULL;
+
+  for (list = path_bar->button_list; list; list = list->next)
+    {
+      GtkFilePath *tmp_path;
+
+      tmp_path = (GtkFilePath *) g_object_get_data (G_OBJECT (list->data),
+                                                   "gtk-path-bar-button-path");
+      if (! gtk_file_path_compare (file_path, tmp_path))
+       {
+         current_path = list;
+         break;
+       }
+
+    }
+
+  if (current_path)
+    {
+      for (list = path_bar->button_list; list; list = list->next)
+       {
+         update_button_appearance (GTK_WIDGET (list->data),
+                                   (list == current_path) ? TRUE : FALSE);
+       }
+      return TRUE;
+    }
+  return FALSE;
+}
 
 gboolean
-gtk_path_bar_set_path (GtkPathBar         *path_bar,
-                      const GtkFilePath  *file_path,
-                      GtkFileSystem      *file_system,
-                      GError            **error)
+_gtk_path_bar_set_path (GtkPathBar         *path_bar,
+                       const GtkFilePath  *file_path,
+                       GtkFileSystem      *file_system,
+                       GError            **error)
 {
   GtkFilePath *path;
   gboolean first_directory = TRUE;
@@ -645,6 +704,9 @@ gtk_path_bar_set_path (GtkPathBar         *path_bar,
 
   result = TRUE;
 
+  if (gtk_path_bar_check_parent_path (path_bar, file_path, file_system))
+    return TRUE;
+      
   gtk_path_bar_clear_buttons (path_bar);
   path = gtk_file_path_copy (file_path);
 
@@ -691,6 +753,7 @@ gtk_path_bar_set_path (GtkPathBar         *path_bar,
        }
 
       display_name = gtk_file_info_get_display_name (file_info);
+      /* FIXME: Do this better */
       if (! strcmp ("/", display_name))
        display_name = " / ";
       button = make_directory_button (display_name, path, first_directory);
@@ -711,3 +774,41 @@ gtk_path_bar_set_path (GtkPathBar         *path_bar,
 
   return result;
 }
+
+void
+gtk_path_bar_set_root_icon (GtkPathBar *path_bar,
+                           GdkPixbuf  *root_icon)
+{
+  g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
+
+  if (root_icon)
+    path_bar->home_icon = g_object_ref (root_icon);
+
+  if (path_bar->root_icon)
+    g_object_unref (root_icon);
+
+  path_bar->root_icon = root_icon;
+}
+
+void
+gtk_path_bar_set_home_icon (GtkPathBar        *path_bar,
+                           const GtkFilePath *home_directory,
+                           GdkPixbuf         *home_icon)
+{
+  g_return_if_fail (GTK_IS_PATH_BAR (path_bar));
+
+  if (home_icon)
+    g_object_ref (home_icon);
+
+  if (path_bar->home_directory != NULL)
+    gtk_file_path_free (path_bar->home_directory);
+  if (path_bar->home_icon)
+    g_object_unref (home_icon);
+
+  if (home_directory)
+    path_bar->home_directory = gtk_file_path_new_dup (gtk_file_path_get_string (home_directory));
+  else
+    path_bar->home_directory = NULL;
+  path_bar->home_icon = home_icon;
+}
+                   
index f058af2ba4060f10d71d947fcc970865e185a900..3a8537a3da577306b4d5016e5c516d14df2845df 100644 (file)
@@ -40,6 +40,10 @@ struct _GtkPathBar
 {
   GtkContainer parent;
 
+  GtkFilePath *home_directory;
+  GdkPixbuf *home_icon;
+  GdkPixbuf *root_icon;
+
   GList *button_list;
   GList *first_scrolled_button;
   GtkWidget *up_slider_button;
@@ -58,11 +62,17 @@ struct _GtkPathBarClass
                         GtkFilePath *file_path);
 };
 
-GType gtk_path_bar_get_type (void) G_GNUC_CONST;
-gboolean gtk_path_bar_set_path (GtkPathBar         *path_bar,
-                               const GtkFilePath  *file_path,
-                               GtkFileSystem      *file_system,
-                               GError            **error);
+GType    gtk_path_bar_get_type (void) G_GNUC_CONST;
+gboolean _gtk_path_bar_set_path (GtkPathBar         *path_bar,
+                                const GtkFilePath  *file_path,
+                                GtkFileSystem      *file_system,
+                                GError            **error);
+void     _gtk_path_bar_set_root_icon (GtkPathBar         *path_bar,
+                                     GdkPixbuf          *home_icon);
+void     _gtk_path_bar_set_home_icon (GtkPathBar         *path_bar,
+                                     const GtkFilePath  *home_dir,
+                                     GdkPixbuf          *home_icon);
+
 G_END_DECLS
 
 #endif /* __GTK_PATH_BAR__ */